//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <ddk.h>
#include "gpio.h"

typedef struct {
    unsigned long gpin;
    unsigned long direct;/*0: in, 1: out*/
    unsigned long level;/**/
    unsigned long altfn;
}sGPIO_TBL;

//sGPIO_TBL GPIO[] = {
///* GPIO PIN NAME		DIRECT LEVEL    ALTFUNC*/ // PIN#
//    {GPIO_P_PMU_IRQ,        0,  0,      0},     //0/
//    {GPIO_P_EJACK_RECO,     0,  0,      0},     //1/
//    {GPIO_P_SYS_EN,         0,  0,      0},     //2/
//    {GPIO_P_PWR_SCL,        1,  0,      0},     //3/
//    {GPIO_P_PWR_SDA,        0,  0,      0},     //4/
//    {GPIO_PWR_CAP0,         0,  0,      0},     //5/
//    {GPIO_PWR_CAP1,         0,  0,      0},     //6/
//    {GPIO_PWR_CAP2,         0,  0,      0},     //7/
//    {GPIO_PWR_CAP3,         0,  0,      0},     //8/
//    {GPIO_P_AC97_13M,       1,  0,      3},     //9/
//    {GPIO_P_BB_32K,         1,  0,      1},     //10/
//    {GPIO_EMPTY0,           1,  0,      0},     //11
//    {GPIO_P_CIF_DD7,        0,  0,      2},     //12/
//    {GPIO_P_SPI_TXD,        1,  0,      1},     //13/
//    {GPIO_P_SPI_FRM,        1,  0,      0},     //14/
//    {GPIO_P_FASTSLEEP,      0,  0,      0},     //15/
//    {GPIO_P_LCD_BLCTL,      1,  0,      2},     //16/
//    {GPIO_P_CIF_DD6,        0,  0,      2},     //17/
//    {GPIO_EMPTY1,           1,  0,      0},     //18
//    {GPIO_P_BT_WAKE,        1,  0,      0},     //19/
//    {GPIO_P_DOC_IRQ,        0,  0,      0},     //20/
//    {GPIO_EMPTY2,           1,  0,      0},     //21
//    {GPIO_P_BB_FLASH,       1,  0,      0},     //22/
//    {GPIO_P_BB_RESETN,      1,  0,      0},     //23/
//    {GPIO_P_LCD_nRESET,     1,  0,      0},     //24/Rising edge
//    {GPIO_P_ONKEY_N,        1,  1,      0},     //25/1:On,0:Off
//    {GPIO_RTS0,             0,  0,      3},     //26/
//    {GPIO_CTS0,             1,  0,      3},     //27/
//    {GPIO_P_AC97_BITCLK,    0,  0,      1},     //28/
//    {GPIO_P_AC97_SDIN,      0,  0,      1},     //29/
//    {GPIO_P_AC97_SDOUT,     1,  0,      2},     //30/
//    {GPIO_P_AC97_SYNC,      1,  0,      2},     //31/
//    {GPIO_P_SDIO_CLK,       1,  0,      2},     //32/
//    {GPIO_EMPTY3,           1,  0,      0},     //33
//    {GPIO_TXD0,             0,  0,      1},     //34/
//    {GPIO_P_SDIO_CD,        0,  0,      0},     //35/
//    {GPIO_P_SPI_SCLK,       1,  0,      2},     //36/
//    {GPIO_RXD0,             1,  0,      3},     //37/
//    {GPIO_P_BB_HOST_WAKEUP, 0,  0,      0},     //38/
//    {GPIO_EMPTY4,           1,  0,      0},     //39
//    {GPIO_P_USB_FULL_SPEED, 1,  0,      0},     //40/
//    {GPIO_P_USB_OTG_ID,     0,  0,      0},     //41/
//    {GPIO_P_BT_TXD,         0,  0,      1},     //42/
//    {GPIO_P_BT_RXD,         1,  0,      2},     //43/
//    {GPIO_P_BT_RTS,         0,  0,      1},     //44/
//    {GPIO_P_BT_CTS,         1,  0,      2},     //45/
//    {GPIO_P_RXD0,           0,  0,      2},     //46/
//    {GPIO_P_TXD0,           1,  0,      1},     //47/
//    {GPIO_P_CIF_DD5,        0,  0,      1},     //48/
//    {GPIO_EMPTY5,           1,  0,      0},     //49
//    {GPIO_P_CIF_DD3,        0,  0,      1},     //50/
//    {GPIO_P_CIF_DD2,        0,  0,      1},     //51/
//    {GPIO_P_AUDIO_PWREN ,   1,  0,      0},     //52/
//    {GPIO_P_CIF_MCLK ,      1,  0,      2},     //53/
//    {GPIO_P_CIF_PCLK,       0,  0,      3},     //54/
//    {GPIO_P_CIF_DD1,        0,  0,      1},     //55/
//    {GPIO_P_CIF_PWRDN,      1,  0,      0},     //56/
//    {GPIO_P_CIF_nRESET,     1,  0,      0},     //57/Rising edge
//    {GPIO_P_L_DD0,          1,  0,      2},     //58/
//    {GPIO_P_L_DD1,          1,  0,      2},     //59/
//    {GPIO_P_L_DD2,          1,  0,      2},     //60/
//    {GPIO_P_L_DD3,          1,  0,      2},     //61/
//    {GPIO_P_L_DD4,          1,  0,      2},     //62/
//    {GPIO_P_L_DD5,          1,  0,      2},     //63/
//    {GPIO_P_L_DD6,          1,  0,      2},     //64/
//    {GPIO_P_L_DD7,          1,  0,      2},     //65/
//    {GPIO_P_L_DD8,          1,  0,      2},     //66/
//    {GPIO_P_L_DD9,          1,  0,      2},     //67/
//    {GPIO_P_L_DD10,         1,  0,      2},     //68/
//    {GPIO_P_L_DD11,         1,  0,      2},     //69/
//    {GPIO_P_L_DD12,         1,  0,      2},     //70/
//    {GPIO_P_L_DD13,         1,  0,      2},     //71/
//    {GPIO_P_L_DD14,         1,  0,      2},     //72/
//    {GPIO_P_L_DD15,         1,  0,      2},     //73/
//    {GPIO_P_LFCLK_RD,       1,  0,      2},     //74/
//    {GPIO_P_LLCLK_A0,       1,  0,      2},     //75/
//    {GPIO_P_LPCLK_WR,       1,  0,      2},     //76/
//    {GPIO_P_LCD_BIAS,       1,  0,      0},     //77/
//    {GPIO_BTOSC_EN,         1,  0,      0},     //78/
//    {GPIO_P_SDIO_PWREN ,    1,  0,      0},     //79/
//    {GPIO_EMPTY6,           1,  0,      0},     //80
//    {GPIO_P_CIF_DD0,        0,  0,      2},     //81/
//    {GPIO_P_BT_PWREN,       1,  0,      0},     //82/
//    {GPIO_P_CIF_DD4,        0,  0,      3},     //83/
//    {GPIO_P_CIF_FV,         0,  0,      3},     //84/
//    {GPIO_P_CIF_LV,         0,  0,      3},     //85/
//    {GPIO_EMPTY7,           1,  0,      0},     //86
//    {GPIO_EMPTY8,           1,  0,      0},     //87
//    {GPIO_P_PA_SHUTDN,      1,  1,      0},     //88/
//    {GPIO_P_VIB_PWREN,      1,  0,      0},     //89/
//    {GPIO_P_HOST_WAKE,      0,  0,      0},     //90/
//    {GPIO_EMPTY9,           1,  0,      0},     //91
//    {GPIO_P_SDIO_DAT0,      0,  0,      1},     //92/
//    {GPIO_EMPTY10,          1,  0,      0},     //93
//    {GPIO_EMPTY11,          1,  0,      0},     //94
//    {GPIO_EMPTY12,          1,  0,      0},     //95
//    {GPIO_P_KP_MKOUT6,      1,  0,      3},     //96/
//    {GPIO_P_KP_MKIN3,       0,  0,      3},     //97/
//    {GPIO_P_KP_MKIN4,       0,  0,      3},     //98/
//    {GPIO_P_KP_MKIN5,       0,  0,      3},     //99/
//    {GPIO_P_KP_MKIN0,       0,  0,      1},     //100/
//    {GPIO_P_KP_MKIN1,       0,  0,      1},     //101/
//    {GPIO_P_KP_MKIN2,       0,  0,      1},     //102/
//    {GPIO_P_KP_MKOUT0,      1,  0,      2},     //103/
//    {GPIO_P_KP_MKOUT1,      1,  0,      2},     //104/
//    {GPIO_P_KP_MKOUT2,      1,  0,      2},     //105/
//    {GPIO_EMPTY13,          1,  0,      0},     //106
//    {GPIO_P_USB_DEC_N,      0,  0,      0},     //107/
//    {GPIO_P_KP_MKOUT5,      1,  0,      2},     //108/
//    {GPIO_P_SDIO_DAT1,      0,  0,      1},     //109/
//    {GPIO_P_SDIO_DAT2,      0,  0,      1},     //110/
//    {GPIO_P_SDIO_DAT3,      0,  0,      1},     //111/
//    {GPIO_P_SDIO_CMD,       0,  0,      1},     //112/
//    {GPIO_P_AC97_nRST,      1,  0,      2},     //113/
//    {GPIO_P_MODEM_WAKEUP,   1,  0,      0},     //114/
//    {GPIO_BT_RST_N,         1,  0,      0},     //115/
//    {GPIO_P_AC97_INT,       0,  0,      0},     //116/
//    {GPIO_P_I2C_SCL,        1,  0,      1},     //117/
//    {GPIO_P_I2C_SDA,        0,  0,      1},     //118/
//    {GPIO_EMPTY14,          1,  0,      0},     //119
//    {GPIO_EMPTY15,          1,  0,      0},     //120
//};

sGPIO_TBL GPIO[] = {
/* GPIO PIN NAME		DIRECT LEVEL    ALTFUNC*/ // PIN#
    {GPIO_P_PMU_IRQ,        0,  0,      0},     //0/
    {GPIO_P_EJACK_RECO,     0,  0,      0},     //1/
    {GPIO_P_SYS_EN,         0,  0,      0},     //2/
    {GPIO_P_PWR_SDA,        0,  0,      0},     //4/
    {GPIO_PWR_CAP0,         0,  0,      0},     //5/
    {GPIO_PWR_CAP1,         0,  0,      0},     //6/
    {GPIO_PWR_CAP2,         0,  0,      0},     //7/
    {GPIO_PWR_CAP3,         0,  0,      0},     //8/
    {GPIO_P_CIF_DD7,        0,  0,      2},     //12/
    {GPIO_P_FASTSLEEP,      0,  0,      0},     //15/
    {GPIO_P_CIF_DD6,        0,  0,      2},     //17/
    {GPIO_P_DOC_IRQ,        0,  0,      0},     //20/
    {GPIO_RTS0,             0,  0,      3},     //26/
    {GPIO_P_AC97_BITCLK,    0,  0,      1},     //28/
    {GPIO_P_AC97_SDIN,      0,  0,      1},     //29/
    {GPIO_TXD0,             0,  0,      1},     //34/
    {GPIO_P_SDIO_CD,        0,  0,      0},     //35/
    {GPIO_P_BB_HOST_WAKEUP, 0,  0,      0},     //38/
    {GPIO_P_USB_OTG_ID,     0,  0,      0},     //41/
    {GPIO_P_BT_TXD,         0,  0,      1},     //42/
    {GPIO_P_BT_RTS,         0,  0,      1},     //44/
    {GPIO_P_RXD0,           0,  0,      2},     //46/
    {GPIO_P_CIF_DD5,        0,  0,      1},     //48/
    {GPIO_P_CIF_DD3,        0,  0,      1},     //50/
    {GPIO_P_CIF_DD2,        0,  0,      1},     //51/
    {GPIO_P_CIF_PCLK,       0,  0,      3},     //54/
    {GPIO_P_CIF_DD1,        0,  0,      1},     //55/
    {GPIO_P_CIF_DD0,        0,  0,      2},     //81/
    {GPIO_P_CIF_DD4,        0,  0,      3},     //83/
    {GPIO_P_CIF_FV,         0,  0,      3},     //84/
    {GPIO_P_CIF_LV,         0,  0,      3},     //85/
    {GPIO_P_HOST_WAKE,      0,  0,      0},     //90/
    {GPIO_P_SDIO_DAT0,      0,  0,      1},     //92/
    {GPIO_P_KP_MKIN3,       0,  0,      3},     //97/
    {GPIO_P_KP_MKIN4,       0,  0,      3},     //98/
    {GPIO_P_KP_MKIN5,       0,  0,      3},     //99/
    {GPIO_P_KP_MKIN0,       0,  0,      1},     //100/
    {GPIO_P_KP_MKIN1,       0,  0,      1},     //101/
    {GPIO_P_KP_MKIN2,       0,  0,      1},     //102/
    {GPIO_P_USB_DEC_N,      0,  0,      0},     //107/
    {GPIO_P_SDIO_DAT1,      0,  0,      1},     //109/
    {GPIO_P_SDIO_DAT2,      0,  0,      1},     //110/
    {GPIO_P_SDIO_DAT3,      0,  0,      1},     //111/
    {GPIO_P_SDIO_CMD,       0,  0,      1},     //112/
    {GPIO_P_AC97_INT,       0,  0,      0},     //116/
    {GPIO_P_I2C_SDA,        0,  0,      1},     //118/

//    {GPIO_P_PWR_SCL,        1,  0,      0},     //3/
//    {GPIO_P_AC97_13M,       1,  0,      3},     //9/
//    {GPIO_P_BB_32K,         1,  0,      1},     //10/
//    {GPIO_P_SPI_TXD,        1,  0,      1},     //13/
//    {GPIO_P_SPI_FRM,        1,  0,      0},     //14/
//    {GPIO_P_LCD_BLCTL,      1,  0,      2},     //16/
//    {GPIO_P_BT_WAKE,        1,  0,      0},     //19/
//    {GPIO_P_BB_FLASH,       1,  0,      0},     //22/
//    {GPIO_P_BB_RESETN,      1,  0,      0},     //23/
//    {GPIO_CTS0,             1,  0,      3},     //27/
    {GPIO_P_AC97_SDOUT,     1,  0,      2},     //30/
    {GPIO_P_AC97_SYNC,      1,  0,      2},     //31/
    {GPIO_P_SDIO_CLK,       1,  0,      2},     //32/
//    {GPIO_P_SPI_SCLK,       1,  0,      2},     //36/
//    {GPIO_RXD0,             1,  0,      3},     //37/
//    {GPIO_P_USB_FULL_SPEED, 1,  0,      0},     //40/
//    {GPIO_P_BT_RXD,         1,  0,      2},     //43/
//    {GPIO_P_BT_CTS,         1,  0,      2},     //45/
    {GPIO_P_TXD0,           1,  0,      1},     //47/
//    {GPIO_P_CIF_MCLK ,      1,  0,      2},     //53/
//    {GPIO_P_L_DD0,          1,  0,      2},     //58/
//    {GPIO_P_L_DD1,          1,  0,      2},     //59/
//    {GPIO_P_L_DD2,          1,  0,      2},     //60/
//    {GPIO_P_L_DD3,          1,  0,      2},     //61/
//    {GPIO_P_L_DD4,          1,  0,      2},     //62/
//    {GPIO_P_L_DD5,          1,  0,      2},     //63/
//    {GPIO_P_L_DD6,          1,  0,      2},     //64/
//    {GPIO_P_L_DD7,          1,  0,      2},     //65/
//    {GPIO_P_L_DD8,          1,  0,      2},     //66/
//    {GPIO_P_L_DD9,          1,  0,      2},     //67/
//    {GPIO_P_L_DD10,         1,  0,      2},     //68/
//    {GPIO_P_L_DD11,         1,  0,      2},     //69/
//    {GPIO_P_L_DD12,         1,  0,      2},     //70/
//    {GPIO_P_L_DD13,         1,  0,      2},     //71/
//    {GPIO_P_L_DD14,         1,  0,      2},     //72/
//    {GPIO_P_L_DD15,         1,  0,      2},     //73/
//    {GPIO_P_LFCLK_RD,       1,  0,      2},     //74/
//    {GPIO_P_LLCLK_A0,       1,  0,      2},     //75/
//    {GPIO_P_LPCLK_WR,       1,  0,      2},     //76/
//    {GPIO_P_LCD_BIAS,       1,  0,      0},     //77/
//    {GPIO_BTOSC_EN,         1,  0,      0},     //78/
    {GPIO_P_KP_MKOUT6,      1,  0,      3},     //96/
    {GPIO_P_KP_MKOUT0,      1,  0,      2},     //103/
    {GPIO_P_KP_MKOUT1,      1,  0,      2},     //104/
    {GPIO_P_KP_MKOUT2,      1,  0,      2},     //105/
    {GPIO_P_KP_MKOUT5,      1,  0,      2},     //108/
    {GPIO_P_AC97_nRST,      1,  0,      2},     //113/
//    {GPIO_P_MODEM_WAKEUP,   1,  0,      0},     //114/
//    {GPIO_BT_RST_N,         1,  0,      0},     //115/
//    {GPIO_P_I2C_SCL,        1,  0,      1},     //117/

//    {GPIO_P_LCD_nRESET,     1,  0,      0},     //24/Rising edge
//    {GPIO_P_ONKEY_N,        1,  1,      0},     //25/1:On,0:Off
    {GPIO_P_AUDIO_PWREN ,   1,  0,      0},     //52/
//    {GPIO_P_CIF_PWRDN,      1,  0,      0},     //56/
//    {GPIO_P_CIF_nRESET,     1,  0,      0},     //57/Rising edge
    {GPIO_P_SDIO_PWREN ,    1,  1,      0},     //79/
//    {GPIO_P_BT_PWREN,       1,  0,      0},     //82/
    {GPIO_P_PA_SHUTDN,      1,  1,      0},     //88/
//    {GPIO_P_VIB_PWREN,      1,  0,      0},     //89/

    {GPIO_EMPTY0,           1,  0,      0},     //11
    {GPIO_EMPTY1,           1,  0,      0},     //18
//    {GPIO_EMPTY2,           1,  0,      0},     //21??
//    {GPIO_EMPTY3,           1,  0,      0},     //33
//    {GPIO_EMPTY4,           1,  0,      0},     //39
    {GPIO_EMPTY5,           1,  0,      0},     //49
    {GPIO_EMPTY6,           1,  0,      0},     //80
    {GPIO_EMPTY7,           1,  0,      0},     //86
    {GPIO_EMPTY8,           1,  0,      0},     //87
    {GPIO_EMPTY9,           1,  0,      0},     //91
//    {GPIO_EMPTY10,          1,  0,      0},     //93??
    {GPIO_EMPTY11,          1,  0,      0},     //94
//    {GPIO_EMPTY12,          1,  0,      0},     //95?
    {GPIO_EMPTY13,          1,  0,      0},     //106
//    {GPIO_EMPTY14,          1,  0,      0},     //119
//    {GPIO_EMPTY15,          1,  0,      0},     //120
};

void GPIO_Reset()
{
    unsigned long pGPDR[4] = {0, 0, 0, 0};
    unsigned long pGPSR[4] = {0, 0, 0, 0};
    unsigned long pGPCR[4] = {0, 0, 0, 0};
    unsigned long pGAFR[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    for (unsigned int i = 0; i < sizeof(GPIO)/sizeof(sGPIO_TBL); i++) {
        int x = GPIO[i].gpin >> 4;
        int y = (GPIO[i].gpin & 0x0f) << 1;

        pGAFR[x] &= ~(3 << y);
        pGAFR[x] |= (GPIO[i].altfn << y);

        x = GPIO[i].gpin >> 5;
        y = GPIO[i].gpin & 0x1f;

        if (GPIO[i].direct == 0) {//In
            pGPDR[x] &= ~(0x1 << y);
        }
        else {//Out
            if (GPIO[i].level == 0) {//Low
                pGPCR[x] |= (0x1 << y);
            }
            else {//High
                pGPSR[x] |= (0x1 << y);
            }

            pGPDR[x] |= (0x1 << y);
        }
    }

    GPIO_REGS * pGPIO = (GPIO_REGS *)0x80E00000;
    pGPIO->GAFR0_L = pGAFR[0];
    pGPIO->GAFR0_U = pGAFR[1];
    pGPIO->GAFR1_L = pGAFR[2];
    pGPIO->GAFR1_U = pGAFR[3];
    pGPIO->GAFR2_L = pGAFR[4];
    pGPIO->GAFR2_U = pGAFR[5];
    pGPIO->GAFR3_L = pGAFR[6];
    pGPIO->GAFR3_U = pGAFR[7];

//    pGPIO->GPCR0 = pGPCR[0];
//    pGPIO->GPCR1 = pGPCR[1];
//    pGPIO->GPCR2 = pGPCR[2];
//    pGPIO->GPCR3 = pGPCR[3];
//
//    pGPIO->GPSR0 = pGPSR[0];
//    pGPIO->GPSR1 = pGPSR[1];
//    pGPIO->GPSR2 = pGPSR[2];
//    pGPIO->GPSR3 = pGPSR[3];

    pGPIO->GPDR0 = pGPDR[0];
    pGPIO->GPDR1 = pGPDR[1];
    pGPIO->GPDR2 = pGPDR[2];
    pGPIO->GPDR3 = pGPDR[3];

    return ;
}
